home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / spacewar / cmd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-05-31  |  11.2 KB  |  511 lines

  1. /*
  2.  * Spacewar - get and process player commands doing character/line editing
  3.  *
  4.  * Copyright 1984 obo Systems, Inc.
  5.  * Copyright 1984 Dan Rosenblatt
  6.  */
  7.  
  8. #ifndef VMS
  9. #include <sys/types.h>
  10. #include <dbm.h>
  11. #else /* BSD SYSIII SYSV */
  12. #include <types.h>
  13. #include "dbm.h"
  14. #endif /* VMS */
  15. #include <errno.h>
  16. #include "spacewar.h"
  17. #include "universe.h"
  18. #include "login.h"
  19. #include "uio.h"
  20. #include "plyr.h"
  21. #include "mlbx.h"
  22. #ifdef VMS
  23. #    include <iodef.h>
  24. #    include <ssdef.h>
  25.     short inmlbx;
  26. #endif /* VMS */
  27.  
  28. int doproctrap,doupdate;
  29. static struct login *getinp();
  30. static VOID cmd2();
  31. extern VOID prvcmd();
  32.  
  33. VOID cmd()
  34. {
  35.     register struct login *plogin;
  36.  
  37. #ifdef DEBUG
  38.     DBG("cmd()\n");
  39. #endif
  40.  
  41.     /* get and process a command */
  42.     if (!(plogin = getinp())) {
  43. #ifdef DEBUG
  44.         VDBG("cmd return\n");
  45. #endif
  46.         return;
  47.     }
  48.  
  49.     /* based on current major command */
  50. #ifdef DEBUG
  51.     VDBG("cmd: stat #%d '%c'\n",plogin-loginlst,plogin->ln_stat);
  52. #endif
  53.     switch(plogin->ln_stat) {
  54.  
  55.         case 'M':    /* Mail (Complain) */
  56.             doupdate = 0;
  57.             mail(plogin);
  58.             if (doupdate == 0) doupdate = 1;
  59.             break;
  60.  
  61.         case 'B':    /* reBuild */
  62.             doupdate = 0;
  63.             build(plogin);
  64.             if (doupdate == 0) doupdate = 1;
  65.             break;
  66.  
  67.         case 'S':    /* See */
  68.             doupdate = 0;
  69.             see(plogin);
  70.             if (doupdate == 0) doupdate = 1;
  71.             break;
  72.  
  73.         case 'U':    /* Usercmd */
  74.             doupdate = 0;
  75.             usrcmd(plogin);
  76.             if (doupdate == 0) doupdate = 1;
  77.             break;
  78.  
  79.         case 'W':    /* Who */
  80.             doupdate = 0;
  81.             who(plogin);
  82.             if (doupdate == 0) doupdate = 1;
  83.             break;
  84.  
  85.         case 'P':    /* Play */
  86.             doupdate = 0;
  87.             play(plogin);
  88.             if (doupdate == 0) doupdate = 1;
  89.             break;
  90.  
  91.         default:    /* not doing anything yet */
  92.             doupdate = 0;
  93.             cmd2(plogin);
  94.             if (doupdate == 0) doupdate = 1;
  95.             break;
  96.     }
  97.  
  98.     plogin->ln_input[0] = NULL;
  99. #ifdef DEBUG
  100.     VDBG("cmd return\n");
  101. #endif
  102. }
  103.  
  104. static VOID cmd2(plogin)
  105. register struct login *plogin;
  106. {
  107.     int inplen=strlen(plogin->ln_input);
  108.     struct plyrkey getplkey;
  109.     struct plyr getpldat;
  110.     datum dbmkey,dbmdata;
  111.  
  112. #ifdef DEBUG
  113.     DBG("cmd2()\n");
  114. #endif
  115.  
  116.     /********************/
  117.     /* response is name */
  118.     /********************/
  119.     if (!plogin->ln_name[0]) { /* no name */
  120.  
  121. #ifdef DEBUG
  122.         VDBG("cmd2: #%d response is name\n",plogin-loginlst);
  123. #endif
  124.  
  125.         /* do again if too short or long */
  126.         if (inplen < 2 || inplen >= sizeof(plogin->ln_name)) {
  127.             output(plogin,'C',0,
  128.             "Name must be 2 to 8 characters\n\nWhat is your name?");
  129.             output(plogin,0,0,0);
  130. #ifdef DEBUG
  131.             VDBG("cmd2 return\n");
  132. #endif
  133.             return;
  134.         }
  135.  
  136.         /* insure no players playing more than once */
  137.         {
  138.             int i;
  139.             struct login *plgn;
  140.  
  141. #ifdef DEBUG
  142.             VDBG("cmd2: #%d checking for dup login (%s)\n",
  143.             plogin-loginlst,plogin->ln_input);
  144. #endif
  145.             for (i=MAXLOGIN,plgn=loginlst;i-- > 0;++plgn) {
  146.                 if (!strcmp(plogin->ln_input,plgn->ln_name)) {
  147.                     output(plogin,'C',0,
  148.                     "Someone is already playing that name.\n\n\
  149. How about another name?");
  150.                     output(plogin,0,0,0);
  151. #ifdef DEBUG
  152.                     VDBG("cmd2 return\n");
  153. #endif
  154.                     return;
  155.                 }
  156.             }
  157.         }
  158.  
  159.         /* store name and prompt for password */
  160.         strcpy(plogin->ln_name,plogin->ln_input);
  161.         output(plogin,'C',0,"Password:");
  162.         output(plogin,0,0,0);
  163.  
  164.         /* set up password state */
  165.         plogin->ln_stat = 'p';
  166.         plogin->ln_iomode = 'p'; /* no echo */
  167.  
  168.     /************************/
  169.     /* response is password */
  170.     /************************/
  171.     } else if (plogin->ln_stat == 'p') { /* password state */
  172.  
  173. #ifdef DEBUG
  174.         VDBG("cmd2: #%d (%s) response is password\n",
  175.         plogin-loginlst,plogin->ln_name);
  176. #endif
  177.  
  178.         /* get player */
  179.         binit((char *)&getplkey,sizeof(getplkey));
  180.         getplkey.pl_plyrkey = PLYR;
  181.         strcpy(getplkey.pl_name,plogin->ln_name);
  182.         dbmkey.dptr = (char *)&getplkey;
  183.         dbmkey.dsize = sizeof(getplkey);
  184.  
  185.         /* found; check password */
  186.         dbmdata = fetch(dbmkey);
  187.         if (dbmdata.dptr) {
  188.  
  189. #ifdef DEBUG
  190.             VDBG("cmd2: #%d (%s) found, checking password\n",
  191.             plogin-loginlst,plogin->ln_name);
  192. #endif
  193.  
  194.             bcopy((char *)&getpldat,dbmdata.dptr,sizeof(getpldat));
  195.  
  196.             /* bad password */
  197.             if (strcmp(plogin->ln_input,getpldat.pl_passwd)) {
  198.                 output(plogin,'C',0,"Incorrect.\n\nPassword:");
  199.                 output(plogin,0,0,0);
  200.  
  201.             /* good password; check for mail and give prompt */
  202.             } else {
  203.                 output(plogin,'C',0,"\n\n");
  204.                 if (getpldat.pl_seenml < getpldat.pl_lstml)
  205.                 output(plogin,'C',0,"You have new mail\n");
  206.  
  207.                 output(plogin,'C',0,PROMPT);
  208.                 output(plogin,0,0,0);
  209.                 plogin->ln_stat = NULL;
  210.                 plogin->ln_iomode = NULL;
  211.  
  212.                 /* update login info */
  213.                 ++getpldat.pl_numlgn;
  214.                 time(&getpldat.pl_lstlgn);
  215.                 dbmdata.dptr = (char *)&getpldat;
  216.                 dbmdata.dsize = sizeof(getpldat);
  217.                 if (store(dbmkey,dbmdata))
  218.                     perror("cmd2: can't update plyr");
  219.             }
  220.  
  221.         /* not found; insert new player */
  222.         } else {
  223.  
  224. #ifdef DEBUG
  225.             VDBG("cmd2: #%d (%s) not found, inserting\n",
  226.             plogin-loginlst,plogin->ln_name);
  227. #endif
  228.  
  229.             /* do again if too short or long */
  230.             if (inplen < 2 || inplen >= sizeof(getpldat.pl_passwd)) {
  231.                 output(plogin,'C',0,
  232.                 "Password must be 2 to 8 characters\n\nPassword:");
  233.                 output(plogin,0,0,0);
  234. #ifdef DEBUG
  235.                 VDBG("cmd2 return\n");
  236. #endif
  237.                 return;
  238.             }
  239.  
  240.             /* initialize new player login */
  241.             binit((char *)&getpldat,sizeof(getpldat));
  242.             strcpy(getpldat.pl_passwd,plogin->ln_input);
  243.             getpldat.pl_numlgn = 1;
  244.             time(&getpldat.pl_lstlgn);
  245.             getpldat.pl_frstml = 1;
  246.  
  247.             /* insert new player */
  248.             dbmdata.dptr = (char *)&getpldat;
  249.             dbmdata.dsize = sizeof(getpldat);
  250.             if (store(dbmkey,dbmdata)) {
  251.                 output(plogin,'C',0,
  252.                 "(sigh) database collision - try another name\
  253. \n\nWhat is your name?");
  254.                 output(plogin,0,0,0);
  255.                 plogin->ln_name[0] = NULL;
  256.  
  257.             /* give prompt */
  258.             } else {
  259.                 output(plogin,'C',0,"\n\n");
  260.                 output(plogin,'C',0,PROMPT);
  261.                 output(plogin,0,0,0);
  262.             }
  263.             plogin->ln_stat = NULL;
  264.             plogin->ln_iomode = NULL;
  265.         }
  266.  
  267.     /***********************/
  268.     /* response is command */
  269.     /***********************/
  270.     } else switch(plogin->ln_input[0]) {
  271.  
  272.         case 'L': case 'l':    /* Logoff */
  273.             logoff(plogin);
  274.             break;
  275.  
  276.         case 'B': case 'b':    /* reBuild */
  277.             plogin->ln_stat = 'B';
  278.             plogin->ln_crft[0] = NULL;
  279.             plogin->ln_substat = NULL;
  280.             plogin->ln_input[0] = NULL;
  281.             build(plogin);
  282.             break;
  283.  
  284.         case 'I': case 'i':    /* Information */
  285.             output(plogin,'C',0,
  286.             "\nGet hold of and read the spacewar documentation\n");
  287.             output(plogin,'C',0,PROMPT);
  288.             output(plogin,0,0,0);
  289.             break;
  290.  
  291.         case 'C': case 'c':    /* Complain -> Mail to Dan */
  292.             plogin->ln_stat = 'M';
  293.             plogin->ln_substat = NULL;
  294.             strcpy(plogin->ln_input,SWMASTER);
  295.             mail(plogin);
  296.             break;
  297.  
  298.         case 'M': case 'm':    /* Mail */
  299.             plogin->ln_stat = 'M';
  300.             plogin->ln_substat = NULL;
  301.             plogin->ln_input[0] = NULL;
  302.             mail(plogin);
  303.             break;
  304.  
  305.         case 'U': case 'u':    /* Usercmd */
  306.             plogin->ln_stat = 'U';
  307.             plogin->ln_substat = NULL;
  308.             plogin->ln_input[0] = NULL;
  309.             usrcmd(plogin);
  310.             break;
  311.  
  312.         case 'S': case 's':    /* See */
  313.             plogin->ln_stat = 'S';
  314.             plogin->ln_substat = NULL;
  315.             plogin->ln_input[0] = NULL;
  316.             see(plogin);
  317.             break;
  318.  
  319.         case 'W': case 'w':    /* Who */
  320.             plogin->ln_stat = 'W';
  321.             plogin->ln_substat = NULL;
  322.             plogin->ln_input[0] = NULL;
  323.             who(plogin);
  324.             break;
  325.  
  326.         case 'P': case 'p':    /* Play */
  327.             plogin->ln_stat = 'P';
  328.             plogin->ln_crft[0] = NULL;
  329.             plogin->ln_substat = NULL;
  330.             plogin->ln_input[0] = NULL;
  331.             play(plogin);
  332.             break;
  333.  
  334.         default:
  335.             prvcmd(plogin);
  336.             output(plogin,'C',0,PROMPT);
  337.             output(plogin,0,0,0);
  338.             break;
  339.     }
  340.  
  341. #ifdef DEBUG
  342.     VDBG("cmd2 return\n");
  343. #endif
  344. }
  345.  
  346. /* get input; return a ptr to where a full command is */
  347. static struct login *getinp()
  348. {
  349.     struct uio inp;
  350.     int i;
  351.     register char *p;
  352.     register char *input;
  353.     extern int errno;
  354. #ifndef BSD
  355. #ifndef VMS
  356. #    include "uio2.h"
  357.     struct uio2 inp2;
  358. #endif /* VMS */
  359. #endif /* BSD */
  360.  
  361. #ifdef DEBUG
  362.     DBG("getinp()\n");
  363. #endif /* DEBUG */
  364.  
  365.     /* get player input allowing asynchronous  */
  366.     /* trap processing; do echo and edit magic */
  367.     /* do all this until there is a full cmd   */
  368.     for (;;) {
  369.  
  370.         /* get the uio header allowing asynch trap processing */
  371.         if (doproctrap < 0 || doupdate < 0) {
  372. #ifdef DEBUG
  373.             VDBG("getinp return\n");
  374. #endif
  375.             return(NULL);
  376.         }
  377.         doproctrap = 1;
  378. #ifdef VMS
  379.         inp.uio_lgn = (struct login *)-1;
  380.         if ((i=sys$qiow(0,inmlbx,IO$_READVBLK,0,0,0,&inp,sizeof(inp),
  381.         0,0,0,0)) != SS$_NORMAL)  {
  382. #ifdef DEBUG
  383.             VDBG("getinp qiow(READVBLK)=%d errno=%d\n",i,errno);
  384. #endif
  385.             if (errno != EINTR)
  386.             perror("read mlbx uio");
  387.             continue;
  388.         }
  389.         if (inp.uio_lgn == (struct login *)-1) continue;
  390. #else /* BSD SYSIII SYSV */
  391.         if (read(0,&inp,sizeof(inp)) != sizeof(inp)) {
  392.             if (errno != EINTR)
  393.                 perror("read uio");
  394.             continue;
  395.         }
  396. #endif /* VMS BSD SYSIII SYSV */
  397.         doproctrap = 0;
  398. #ifdef DEBUG
  399. #ifndef BSD
  400.         if (((int)inp.uio_lgn) >= 0 &&((int)inp.uio_lgn) <= 20) {
  401. #ifdef VMS
  402.             VDBG("getinp: uio sig %d %s\n",(int)inp.uio_lgn,
  403.             inp.uio_chrs);
  404. #else /* SYSIII SYSV */
  405.             bcopy((char *)&inp2,(char *)&inp,sizeof(inp2));
  406.             VDBG("getinp: uio sig %d %d %s\n",inp2.uio2sig,
  407.             inp2.uio2pid,inp2.uio2tty);
  408. #endif /* VMS SYSIII SYSV */
  409.         } else
  410. #endif /* BSD */
  411.         {
  412.             VDBG("getinp: uio #%d '",inp.uio_lgn-loginlst);
  413.             for (p=inp.uio_chrs;*p;++p)
  414.                 VDBG((*p < ' ' || *p > '~') ? "\\%03o" : "%c",*p);
  415.             VDBG("'\n");
  416.         }
  417. #endif /* DEBUG */
  418.  
  419.         /* validate login pointer */
  420. #ifndef BSD
  421.         if (((int)inp.uio_lgn) >= 0 &&((int)inp.uio_lgn) <= 20) {
  422. #ifdef VMS
  423.             proctrap(inp);
  424. #else /* SYSIII SYSV */
  425.             bcopy((char *)&inp2,(char *)&inp,sizeof(inp2));
  426.             proctrap(inp2);
  427. #endif /* VMS SYSIII SYSV */
  428.             continue;
  429.         }
  430. #endif /* BSD */
  431.         if (inp.uio_lgn < loginlst ||
  432.         inp.uio_lgn >= loginlst+MAXLOGIN) {
  433.             perror("uio_lgn out of range");
  434.             continue;
  435.         }
  436.  
  437.         /* echo (based on iomode) and edit magic */
  438.         input = inp.uio_lgn->ln_input;
  439.         input += strlen(input);
  440.         for (p=inp.uio_chrs;*p;++p) {
  441.             switch(*p) {
  442.             case '\n':
  443.             case '\r':
  444.                 *input = NULL;
  445.  
  446.                 /* strip trailing blanks */
  447.                 for (p=inp.uio_lgn->ln_input;--input >= p &&
  448.                 *input == ' ';)
  449.                 *input = NULL;
  450.  
  451.                 if (inp.uio_lgn->ln_iomode == 'm' ||
  452.                 inp.uio_lgn->ln_iomode == 's')
  453.                 output(inp.uio_lgn,'C',0,"\r");
  454.                 else
  455.                 output(inp.uio_lgn,'C',0,"\n");
  456.                 output(inp.uio_lgn,0,0,0);
  457. #ifdef DEBUG
  458.                 VDBG("getinp return\n");
  459. #endif /* DEBUG */
  460.                 return(inp.uio_lgn);
  461.  
  462.             case '\025':    /* control-U */
  463.                 if (inp.uio_lgn->ln_iomode == 's') {
  464.                 output(inp.uio_lgn,'D',0,0);
  465.                 input = inp.uio_lgn->ln_input;
  466.                 } else {
  467.                 for (i=strlen(inp.uio_lgn->ln_input);i-- > 0;) {
  468.                     --input;
  469.                     output(inp.uio_lgn,'C',0,"\b \b");
  470.                 }
  471.                 }
  472.                 break;
  473.  
  474.             case '\b':
  475.                 if (input > inp.uio_lgn->ln_input) {
  476.                 --input;
  477.                 output(inp.uio_lgn,'C',0,"\b \b");
  478.                 }
  479.                 break;
  480.             }
  481.  
  482.             /* ignore all non-printing chars */
  483.             if (*p < ' ' || *p > '~') continue;
  484.  
  485.             /* make sure buffer can't overflow */
  486.             if (input >= inp.uio_lgn->ln_input +
  487.             sizeof(inp.uio_lgn->ln_input) - 1) {
  488.             *input = NULL;
  489.             if (inp.uio_lgn->ln_iomode == 'm' ||
  490.             inp.uio_lgn->ln_iomode == 's')
  491.                 output(inp.uio_lgn,'C',0,"\r");
  492.             else
  493.                 output(inp.uio_lgn,'C',0,"\n");
  494.             output(inp.uio_lgn,0,0,0);
  495. #ifdef DEBUG
  496.             VDBG("getinp return\n");
  497. #endif /* DEBUG */
  498.             return(inp.uio_lgn);
  499.             }
  500.  
  501.             input[1] = NULL;
  502.             *input = *p;
  503.             output(inp.uio_lgn,'C',0,(inp.uio_lgn->ln_iomode == 'p') ?
  504.             " " : input); /* space if password state, char otherwise */
  505.             ++input;
  506.         }
  507.         *input = NULL;
  508.         output(inp.uio_lgn,0,0,0);
  509.     }
  510. }
  511.